package com.sy.simpleegg.platform.ychsdk

import android.util.ArrayMap
import com.google.gson.reflect.TypeToken
import com.sy.simpleegg.ext.logFile
import com.sy.simpleegg.platform.ychsdk.bean.HeartResp
import com.sy.simpleegg.platform.ychsdk.bean.MqGetSettingData
import com.sy.simpleegg.platform.ychsdk.bean.YchBuyPackageBean
import com.sy.simpleegg.platform.ychsdk.bean.YchBuyPackageResp
import com.sy.simpleegg.platform.ychsdk.bean.YchGoodBean
import com.sy.simpleegg.platform.ychsdk.bean.config.GetPayCoinData
import com.sy.simpleegg.platform.ychsdk.bean.config.GetPayQrCodeData
import com.sy.simpleegg.platform.ychsdk.bean.good.GoodsCoinResponse
import com.sy.simpleegg.platform.ychsdk.bean.good.RechargeGoodsData
import com.sy.simpleegg.platform.ychsdk.bean.login.LoginToken
import com.sy.simpleegg.platform.ychsdk.bean.member.GetMemberLoginQrCode
import com.sy.simpleegg.platform.ychsdk.bean.member.QrCodeMemberInfoResponse
import com.sy.simpleegg.platform.ychsdk.bean.member.SaveCoinResult
import com.sy.simpleegg.platform.ychsdk.bean.pay.ChannelWaitOffData
import com.sy.simpleegg.platform.ychsdk.bean.pay.PayResult
import com.sy.simpleegg.platform.ychsdk.bean.pay.RepCashDataBean
import com.sy.simpleegg.platform.ychsdk.constant.Constant
import com.sy.simpleegg.platform.ychsdk.manager.YchBusinessManager
import com.sy.simpleegg.platform.ychsdk.manager.YchInitApiManager
import com.sy.simpleegg.util.BigDecimalUtil
import com.sy.simpleegg.util.GsonUtil
import com.ych.ytdevicesdk.DeviceManager
import com.ych.ytdevicesdk.IDeviceManager
import com.ych.ytdevicesdk.IDeviceManager.IConnectTestResponse
import com.ych.ytdevicesdk.api.BaseResult
import com.ych.ytdevicesdk.entity.AppInfoEntity
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.json.JSONObject
import java.lang.Thread.sleep


class YchClient(
    private val ssid: String,
    private val mainBoardNum: String,
    private val agreement: Int,
    private val agreementVer: String,
    private val devType: String,
    private val title: String,
    private val appSoftVer: Int,
    private val netIp: String,
    private val netMask: String,
    private val netGateWay: String,
    private val ychClientListener: YchClientListener,
) {
    private var deviceManager: IDeviceManager? = null
    private var businessManager: YchBusinessManager? = null

    private var devNum: String? = null

    private var token = ""

    private var normalPackageList: MutableList<YchGoodBean> = mutableListOf()
    private var rechargePackageList: MutableList<YchGoodBean> = mutableListOf()

    private var scope = MainScope()
    private var loopHeartJob: Job? = null
    private var loginJob: Job? = null
    private var loop = true
    private var loginLoop = true

    private var jobMap: ArrayMap<String, Job> = ArrayMap<String, Job>()

    private var heartInterval = 30*1000L

    private var extractCoinResult = -1//-1-处理中 0-成功 1-失败

    init {
        val appInfo = AppInfoEntity().apply {
            this.deviceType = devType
            this.appTitle = title
            this.softVer = appSoftVer
        }

        deviceManager = DeviceManager.getInstance()
//        deviceManager = YchDeviceManager.get()
//        deviceManager?.initSdkNew(ssid, mainBoardNum, devType, agreement, agreementVer, appInfo)

        deviceManager?.setInitListener(object : IDeviceManager.InitListener{
            override fun registerFailed(errorCode: Long, errorMsg: String?) {
                logFile("YCH 注册失败 errorCode=$errorCode errorMsg=$errorMsg")
                ychClientListener.registerFailed(errorCode, errorMsg)
            }

            override fun needUpdate(vararg updateAddress: String?) {
                logFile("YCH 需要更新：${GsonUtil.getInstance()?.toJson(updateAddress)}")
                ychClientListener.needUpdate(*updateAddress)
            }

            override fun bindStatus(isSuccess: Boolean, deviceNumber: String?) {
                // 是否绑定 绑定成功后就可以进行业务系统的调用了
                // 绑定失败则需要去后台进行设备绑定到项目
                // deviceNumber 用于生成绑定设备二维码
                logFile("YCH ${if (isSuccess) "已绑定" else "未绑定"} 设备号：$deviceNumber")
                devNum = deviceNumber
                ychClientListener.bindStatus(isSuccess, deviceNumber)
                devNum?.let {
                    if (isSuccess) {
                        initApi(appSoftVer, netIp, netMask, netGateWay, it)
                    }
                }
            }

            override fun onError(type: String?, errorCode: Long, msg: String?) {
                // type 类型指向 IDeviceManager.ErrorType
                logFile("YCH 设备报错：$type errorCode=$errorCode msg=$msg")
                ychClientListener.onError(type, errorCode, msg)
            }
        })
        deviceManager?.setEventListener(object : IDeviceManager.IMqMessageListener{
            override fun deviceBinding() {
                logFile("YCH 设备绑定推送 设备号：$devNum")
                devNum?.let {
                    initApi(appSoftVer, netIp, netMask, netGateWay, it)
                    ychClientListener.deviceBinding(it)
                }
            }

            override fun deviceUnBinding() {
                logFile("YCH 设备解绑")
                ychClientListener.deviceUnBinding()
            }

            override fun deviceReBoot() {
                logFile("YCH 设备重启")
                ychClientListener.deviceReBoot()
            }

            override fun extractCoin(dataJson: String?): Int {
                //{"Amount":2,"Money":1,"OrderID":"b1d50024-343e-64d1-daf9-10304b43bae4"}
                logFile("YCH 设备出币：$dataJson")
                dataJson?.let {
                    try {
                        val orderJson = JSONObject(it)
                        val coins = if (orderJson.has("Amount")) orderJson.getLong("Amount").toString() else "0"
                        val money = if (orderJson.has("Money")) (orderJson.getLong("Money")*100).toString() else "0"
                        val orderId = if (orderJson.has("OrderID")) orderJson.getString("OrderID") else ""
                        ychClientListener.extractCoin(true, coins, money, orderId)
                        extractCoinResult = -1
                        while (extractCoinResult == -1){
                            sleep(1000L)
                        }

                    }catch (e: Exception){
                        e.printStackTrace()
                        logFile("YCH 设备出币订单解析异常：${e.message}")
                    }
                }
                logFile("YCH 出币result=")
                return if (extractCoinResult == -1) 1 else extractCoinResult
            }

            override fun getDeviceSetting(dataJson: String?): MutableMap<Int, Any>? {
                logFile("获取服务器改变设备设置：$dataJson")
                val mqGetSettingData = GsonUtil.getInstance()?.fromJson<MqGetSettingData>(
                    dataJson,
                    object : TypeToken<MqGetSettingData?>() {}.type
                )
                ychClientListener.getDeviceSetting(dataJson)
                return null
            }

            override fun setDeviceSetting(dataJson: String?): Int? {
                logFile("控制板上报了设置变更推送到服务器：$dataJson")
                ychClientListener.setDeviceSetting(dataJson)
                return null
            }

            override fun changeCashPackage() {
                logFile("后台设置的现金套餐变化，推送到设备，设备需要拉取现金套餐")
                ychClientListener.changeCashPackage()
            }

            override fun updateOrder(orderId: String?, transactionId: String?, deviceStatus: Int, remark: String?) {
                logFile("后台设置订单状态：orderId=$orderId transactionId=$transactionId deviceStatus=$deviceStatus remark=$remark")
                ychClientListener.updateOrder(orderId, transactionId, deviceStatus, remark)
            }

            override fun deviceStatues(status: Int) {
                logFile("YCH 后台设置设备状态：$status")
                ychClientListener.deviceStatues(status)
            }
        })

        deviceManager = DeviceManager.getInstance().initSdk(ssid, mainBoardNum, devType, agreement, agreementVer, appInfo)
//        deviceManager?.initSdkNew(ssid, mainBoardNum, devType, agreement, agreementVer, appInfo)

        businessManager = YchBusinessManager.get()
    }

    private fun initApi(appVer: Int, netIp: String, netMask: String, netGateWay: String, devNum: String){
        deviceManager?.macId?.let {
            YchInitApiManager.get().initApi(appVer, netIp, netMask, netGateWay, devNum, it, object : YchInitApiManager.InitListener{
                override fun loginTokenData(loginToken: LoginToken) {
                    Constant.TOKEN = loginToken.Token
                    loopHeart()
                    ychClientListener.loginComplete()
                }
            })
        }
    }

    private fun loopHeart(){
        loopHeartJob?.cancel()

        loopHeartJob = scope.launch (Dispatchers.IO){
            val interval = 1000L
            val overCount = 15
            var checkCount = 0
            var state = 0//0-开始请求 1-有响应 2-异常

            while (loop){
                checkCount = 0
                state = 0

                val wifiStrength = (com.sy.simpleegg.constant.Constant.NETWORK_SIGNAL*5).toString()
                val apMac = ""
                val mqOnline = if (Constant.MQONLINE) "1" else "0"

                businessManager?.heart("0", wifiStrength, apMac, mqOnline, object : Observer<BaseResult<HeartResp?>>{
                    override fun onSubscribe(d: Disposable) {
                        logFile("YCH 开始发送心跳")
                    }

                    override fun onError(e: Throwable) {
                        logFile("YCH 心跳异常：${e.message}")
                        state = 2
                        onComplete()
                    }

                    override fun onComplete() {
                        logFile("YCH 心跳结束")

                    }

                    override fun onNext(t: BaseResult<HeartResp?>) {
                        logFile("YCH 心跳完成：${GsonUtil.getInstance()?.toJson(t)} ${BigDecimalUtil.scientificToPlainString(t.data!!.Time.toString())}")
                        state = 1
                    }
                })

                while(state == 0){
                    delay(interval)
                    checkCount ++
                    if (checkCount >= overCount){
                        //超时
                        state = 2
                    }
                }

                delay(heartInterval)
            }
        }
    }

    /**
     * 提交错误信息
     *
     * @param errorType 错误类型
     * @param errorMsg  错误数据
     */
    fun deviceErrorSubmit(errorType: Int, errorMsg: String){
        deviceManager?.deviceErrorSubmit(errorType, errorMsg)
    }

    /**
     * 获取SDK版本
     *
     * @return 版本信息
     */
    fun getSdkVersion(): String{
        return deviceManager?.sdkVersion?:""
    }

    /**
     * 连接测试
     *
     * @param iConnectTestResponse 连接测试响应
     * @return {@link IDeviceManager}
     */
    fun connectTest(iConnectTestResponse: IConnectTestResponse): IDeviceManager?{
        return deviceManager?.connectTest(iConnectTestResponse)
    }

    /**
     * 调试器，是否开启调试模式
     *
     * @param isOpen     是否开启
     * @param useTestUrl 使用测试服务器
     * @return {@link IDeviceManager}
     */
    fun debugger(isOpen: Boolean, useTestUrl: Boolean): IDeviceManager?{
        return deviceManager?.debugger(isOpen, useTestUrl)
    }

    /**
     * 日志开关，是否开启日志输出
     *
     * @param isOpen 是否开启
     * @return {@link IDeviceManager}
     */
    fun logger(isOpen: Boolean): IDeviceManager?{
        return deviceManager?.logger(isOpen)
    }


    /**
     * 获取二维码
     * @param transactionId 事务id
     * @return 正扫二维码
     */
    fun getQrCode(transactionId: String){
//        businessManager?.getQrCode(transactionId)
    }

    /**
     * 获取兑币套餐
     * @param type 1-普通套餐 2-充值套餐 3-所有套餐
     */
    fun getCoinPackage(type: Int){
        when (type){
            1 -> getNormalPackage()
            2 -> getRechargePackage()
            3 -> getAllPackage()
        }
    }

    /**
     * 获取商品列表
     *
     * @param observer 响应
     * @param <T>      设置类型
     */
    private fun getNormalPackage(){
        businessManager?.getPackageList(object : Observer<BaseResult<GoodsCoinResponse?>> {

            override fun onSubscribe(d: Disposable) {
                logFile("YCH 开始获取普通套餐列表")
            }

            override fun onNext(t: BaseResult<GoodsCoinResponse?>) {
                logFile("YCH 普通套餐列表：${GsonUtil.getInstance()?.toJson(t)}")
                t.data?.let { coinsData ->
                    coinsData.dataList.forEach { normalData ->
                        normalPackageList.add(
                            YchGoodBean().apply {
                                PackageType = 1
                                PackageID = normalData.packageID
                                PakageName = normalData.pakageName
                                Price = BigDecimalUtil.double2Fen(normalData.price)
                                Coins = normalData.coins
                                Subscript = normalData.subscript?:""
                            }
                        )
                    }
                }
            }

            override fun onError(throwable: Throwable) {
                logFile("YCH 获取普通套餐异常：${throwable.message}")
            }

            override fun onComplete() {
                logFile("YCH 获取普通套餐结束")
                ychClientListener.updateCoinsPackage(normalPackageList)
            }
        })
    }

    /**
     * 获取充值套餐
     */
    private fun getRechargePackage(){
        devNum?.let {
            businessManager?.getRechargeList(it, object : Observer<BaseResult<RechargeGoodsData?>> {

                override fun onSubscribe(d: Disposable) {
                    logFile("YCH 开始获取充值套餐列表")
                }

                override fun onNext(t: BaseResult<RechargeGoodsData?>) {
                    logFile("YCH 充值套餐列表：${GsonUtil.getInstance()?.toJson(t)}")
                    t.data?.let { coinsData ->
                        coinsData.data.forEach { rechargeData ->
                            rechargePackageList.add(
                                YchGoodBean().apply {
                                    PackageType = 2
                                    PackageID = rechargeData.iD
                                    PakageName = rechargeData.name
                                    Price = BigDecimalUtil.double2Fen(rechargeData.price)
                                    Coins = rechargeData.currencyCount
                                    OriginalPrice = BigDecimalUtil.double2Fen(rechargeData.originalPrice)
                                    Tags = rechargeData.tags
                                    GavingCount = rechargeData.gavingCount
                                    HasGift = rechargeData.hasGift
                                    GiftName = rechargeData.giftName
                                    CoinShortName = coinsData.coinShortName
                                    IsFault = coinsData.IsFault
                                }
                            )
                        }
                    }
                }

                override fun onError(throwable: Throwable) {
                    logFile("YCH 获取充值套餐异常：${throwable.message}")
                }

                override fun onComplete() {
                    logFile("YCH 获取充值套餐结束")
                    ychClientListener.updateCoinsPackage(rechargePackageList)
                }
            })
        }
    }

    /**
     * 获取所有套餐
     */
    private fun getAllPackage(){
        businessManager?.getPackageList(object : Observer<BaseResult<GoodsCoinResponse?>> {

            override fun onSubscribe(d: Disposable) {
                logFile("YCH 所有套餐-开始获取普通套餐列表")
            }

            override fun onNext(t: BaseResult<GoodsCoinResponse?>) {
                logFile("YCH 所有套餐-普通套餐列表：${GsonUtil.getInstance()?.toJson(t)}")
                t.data?.let { coinsData ->
                    coinsData.dataList.forEach { normalData ->
                        normalPackageList.add(
                            YchGoodBean().apply {
                                PackageType = 1
                                PackageID = normalData.packageID
                                PakageName = normalData.pakageName
                                Price = BigDecimalUtil.double2Fen(normalData.price)
                                Coins = normalData.coins
                                Subscript = normalData.subscript?:""
                            }
                        )
                    }
                }
            }

            override fun onError(throwable: Throwable) {
                logFile("YCH 所有套餐-获取普通套餐异常：${throwable.message}")
            }

            override fun onComplete() {
                logFile("YCH 所有套餐-获取普通套餐结束")
                if (devNum.isNullOrEmpty()){
                    ychClientListener.updateCoinsPackage(normalPackageList)
                }else{
                    businessManager?.getRechargeList(devNum!!, object : Observer<BaseResult<RechargeGoodsData?>> {

                        override fun onSubscribe(d: Disposable) {
                            logFile("YCH 所有套餐-开始获取充值套餐列表")
                        }

                        override fun onNext(t: BaseResult<RechargeGoodsData?>) {
                            logFile("YCH 所有套餐-充值套餐列表：${GsonUtil.getInstance()?.toJson(t)}")
                            t.data?.let { coinsData ->
                                coinsData.data.forEach { rechargeData ->
                                    rechargePackageList.add(
                                        YchGoodBean().apply {
                                            PackageType = 2
                                            PackageID = rechargeData.iD
                                            PakageName = rechargeData.name
                                            Price = BigDecimalUtil.double2Fen(rechargeData.price)
                                            Coins = rechargeData.currencyCount
                                            OriginalPrice = BigDecimalUtil.double2Fen(rechargeData.originalPrice)
                                            Tags = rechargeData.tags
                                            GavingCount = rechargeData.gavingCount
                                            HasGift = rechargeData.hasGift
                                            GiftName = rechargeData.giftName?:""
                                            CoinShortName = coinsData.coinShortName
                                            IsFault = coinsData.IsFault
                                        }
                                    )
                                }
                            }
                        }

                        override fun onError(throwable: Throwable) {
                            logFile("YCH 所有套餐-获取充值套餐异常：${throwable.message}")
                        }

                        override fun onComplete() {
                            logFile("YCH 所有套餐-获取充值套餐结束")
                            val result = mutableListOf<YchGoodBean>()
                            if (normalPackageList.isNotEmpty()){
                                result.addAll(normalPackageList)
                            }
                            if (rechargePackageList.isNotEmpty()){
                                result.addAll(rechargePackageList)
                            }
                            ychClientListener.updateCoinsPackage(result)
                        }
                    })
                }
            }
        })
    }

    /**
     * 获取配置信息，信息包含纸钞购币套餐
     */
    fun getConfig(){
        businessManager?.getConfig(object : Observer<BaseResult<GetPayCoinData?>> {

            override fun onSubscribe(d: io.reactivex.disposables.Disposable) {
                logFile("YCH 开始获取配置")
            }

            override fun onNext(t: BaseResult<GetPayCoinData?>) {
                logFile("YCH 配置信息：${GsonUtil.getInstance()?.toJson(t)}")
                t.data?.let { payCoinData ->
                    ychClientListener.updateConfig(payCoinData)
                }
            }

            override fun onError(throwable: Throwable) {
                logFile("YCH 获取配置信息异常：${throwable.message}")
            }

            override fun onComplete() {
                logFile("YCH 获取配置信息结束")
            }
        })
    }

    /**
     * 上报现金订单
     * @param repCashData 订单数据
     */
    fun repCashData(repCashData: RepCashDataBean){
        businessManager?.repCashData(repCashData, object : Observer<BaseResult<Any?>>{
            override fun onSubscribe(d: Disposable) {
                logFile("YCH 开始上报现金订单")
            }

            override fun onError(e: Throwable) {
                logFile("YCH 上报现金订单异常：${e.message}")
            }

            override fun onComplete() {
                logFile("YCH 上报现金订单结束")
            }

            override fun onNext(t: BaseResult<Any?>) {
                logFile("YCH 上报现金订单完成：${GsonUtil.getInstance()?.toJson(t)}")

            }
        })
    }

    /**
     * 反扫支付二维码下单
     */
    fun placeOrder(buyPackage: YchBuyPackageBean){
        devNum?.let {
            buyPackage.DevNum = it
            businessManager?.placeOrder(buyPackage, object : Observer<BaseResult<YchBuyPackageResp?>>{
                var resp: YchBuyPackageResp? = null
                var transId = ""
                override fun onSubscribe(d: Disposable) {
                    logFile("YCH 开始反扫支付码下单：${GsonUtil.getInstance()?.toJson(buyPackage)}")
                    transId = buyPackage.TransID
                }

                override fun onError(e: Throwable) {
                    logFile("YCH 反扫支付码下单异常：${e.message}")
                    onComplete()
                }

                override fun onComplete() {
                    logFile("YCH 反扫支付码下单结束")
                    resp?.let { respData ->
                        logFile("YCH 查询订单 transid=$transId orderid=${respData.OrderID}")
                        val money = BigDecimalUtil.double2Fen(buyPackage.TotalMoney.toDouble())
                        ychClientListener.onPlaceOrder(transId, respData.OrderID, respData.OrderNum, buyPackage.Items[0].PackageID, buyPackage.TotalCoin.toString(), money)
                        queryPlaceOrder(respData.OrderID)
                    }
                }

                override fun onNext(t: BaseResult<YchBuyPackageResp?>) {
                    logFile("YCH 反扫支付码下单完成：${GsonUtil.getInstance()?.toJson(t)}")
                    resp = t.data
                }
            })
        }
    }

    /**
     * 获取消费二维码
     * @param goodId 套餐id
     * @param type 0-套餐购买二维码 1-设备二维码
     */
    fun getConsumptionCode(goodId: String, type: Int){
        businessManager?.getConsumptionCode(object : Observer<BaseResult<GetPayQrCodeData?>>{
            var gid = ""
            var resp: GetPayQrCodeData? = null
            override fun onSubscribe(d: Disposable) {
                logFile("YCH 开始获取消费二维码")
                gid = goodId
            }

            override fun onError(e: Throwable) {
                logFile("YCH 获取消费二维码异常：${e.message}")
                onComplete()
            }

            override fun onComplete() {
                logFile("YCH 获取消费二维码结束")
                resp?.let {
                    when (type){
                        0 -> {
                            val qrCode = if (it.QRCode.isNotEmpty()) "${it.QRCode}/?tt=2&bi=$gid&type=5&number=$devNum" else it.QRCode
                            ychClientListener.showBuyConsumptionCode(qrCode)
                        }
                        else -> ychClientListener.showDevConsumptionCode(it.QRCode)
                    }

                }
            }

            override fun onNext(t: BaseResult<GetPayQrCodeData?>) {
                logFile("YCH 获取消费二维码完成：${GsonUtil.getInstance()?.toJson(t)}")
                resp = t.data
            }
        })
    }

    /**
     * 上报出币结果(mqtt)
     * @param responseCode 状态码 0-出币成功 1-出币失败
     * @param transId 事务id（订单id）
     */
    fun repMqExtractCoinResult(responseCode: Int, transId: String){
//        deviceManager?.repExtractCoinResult(responseCode, transId)
        extractCoinResult = responseCode
    }

    /**
     * 上报出币结果
     * @param responseCode 状态码 0-出币成功 1-出币失败
     * @param transId 事务id（订单id）
     */
    fun repMqExtractCoinResult(realOutCoins: Long, needOutCoins: Long, result: Int, balance: Long, orderId: String, transId: String){
        businessManager?.repMqOutCoinResult(realOutCoins, needOutCoins, result, balance, orderId, transId, object : Observer<BaseResult<Any?>>{
            override fun onSubscribe(d: Disposable) {
                logFile("YCH 开始上报MQ出币结果")
            }

            override fun onError(e: Throwable) {
                logFile("YCH 上报MQ出币结果异常：${e.message}")
                onComplete()
            }

            override fun onComplete() {
                logFile("YCH 上报MQ出币结果结束")
            }

            override fun onNext(t: BaseResult<Any?>) {
                logFile("YCH 上报MQ出币结果完成：${GsonUtil.getInstance()?.toJson(t)}")
            }
        })
    }

    /**
     * 上报非MQ出币结果
     * @param responseCode 状态码 0-出币成功 1-出币失败
     * @param transId 事务id（订单id）
     */
    fun repNotMqExtractCoinResult(result: Int, orderId: String, msg: String){
        businessManager?.repNotMqOutCoinResult(result, orderId, msg, object : Observer<BaseResult<Any?>>{
            override fun onSubscribe(d: Disposable) {
                logFile("YCH 开始上报非MQ出币结果")
            }

            override fun onError(e: Throwable) {
                logFile("YCH 上报非MQ出币结果异常：${e.message}")
                onComplete()
            }

            override fun onComplete() {
                logFile("YCH 上报非MQ出币结果结束")
            }

            override fun onNext(t: BaseResult<Any?>) {
                logFile("YCH 上报非MQ出币结果完成：${GsonUtil.getInstance()?.toJson(t)}")
            }
        })
    }

    /**
     * 查询下单支付结果
     */
    private fun queryPlaceOrder(orderId: String){
        val job = scope.launch (Dispatchers.IO) {
            val startTime = System.currentTimeMillis()
            val interval = 1000L
            var useTime = 0L
            val overTime = 58*1000L
            var result = -1//未响应数据 0-支付成功，可出币 1-订单状态异常 2-请求异常

            do {
                delay(interval)
                businessManager?.getPayResult(orderId, object : Observer<BaseResult<PayResult?>> {
                    override fun onSubscribe(d: Disposable) {
                        logFile("YCH 开始查询下单支付结果")
                    }

                    override fun onError(e: Throwable) {
                        logFile("YCH 查询下单支付结果异常：${e.message}")
                        result = 2
                        onComplete()
                    }

                    override fun onComplete() {
                        logFile("YCH 查询下单支付结果结束")
                        useTime = System.currentTimeMillis() - startTime + interval
                    }

                    override fun onNext(t: BaseResult<PayResult?>) {
                        logFile("YCH 查询下单支付结果完成：${GsonUtil.getInstance()?.toJson(t)}")
                        result = when (t.data?.Status) {
                            "Unpaid" -> 1
                            "Paying" -> 1
                            "Completed" -> 0
                            "Returned" -> 1
                            "Canceled" -> 1
                            "Returning" -> 1
                            "PartRetur" -> 1
                            "WaitForRefund" -> 1
                            "Payed" -> 0
                            "WaitSend" -> 1
                            "WaitReceive" -> 1
                            else -> 1
                        }
                    }
                })

                while (result == -1){
                    delay(interval)
                }

            }while(useTime < overTime && result != 0)

            ychClientListener.placeOrderResult(orderId, result == 0)
            jobMap.remove(orderId)
        }

        jobMap[orderId] = job
    }

    /**
     * 移除查询订单支付结果任务
     * @param transId 事务id
     */
    fun removeQueryOrder(transId: String){
        jobMap[transId]?.let { job ->
            job.cancel()
            jobMap.remove(transId)
        }
    }

    fun getLoginCode(){
        devNum?.let {
            businessManager?.getMemberLoginCode(it, object : Observer<BaseResult<GetMemberLoginQrCode?>>{
                var resp: GetMemberLoginQrCode? = null
                override fun onSubscribe(d: Disposable) {
                    logFile("YCH 开始获取登录二维码")

                }

                override fun onError(e: Throwable) {
                    logFile("YCH 获取登录二维码异常：${e.message}")
                    onComplete()
                }

                override fun onComplete() {
                    logFile("YCH 获取登录二维码结束")
                    resp?.let {
                        ychClientListener.getLoginCode(it.QRCodeStr, it.TransID)
                        queryLgLogin(it.TransID)
                    }
                }

                override fun onNext(t: BaseResult<GetMemberLoginQrCode?>) {
                    logFile("YCH 获取登录二维码完成：${GsonUtil.getInstance()?.toJson(t)}")
                    resp = t.data
                }
            })
        }
    }

    /**
     * 查询会员扫码登录结果
     * @param transId 登录二维码返回的事务id
     */
    private fun queryLgLogin(transId: String){
        loginJob?.cancel()

        loginJob = scope.launch(Dispatchers.IO) {
            loginLoop = true
            val tid = transId
            var loginStatus = -1//0-等待登录（继续轮询） 1-登录成功 2-登录失败 3-超时未登录
            var useTime = 0L
            val startTime = System.currentTimeMillis()
            val interval = 1000L
            val overTime = 58*1000L
            var resp: QrCodeMemberInfoResponse? = null
            do{
                delay(interval)
                businessManager?.queryLgLogin(tid, object : Observer<BaseResult<QrCodeMemberInfoResponse?>> {
                    override fun onSubscribe(d: Disposable) {
                        logFile("YCH 开始查询会员扫码登录 transId=$transId")
                        loginStatus = -1
                    }

                    override fun onError(e: Throwable) {
                        logFile("YCH 查询会员扫码登录异常：${e.message}")
                        loginStatus = 0
                        onComplete()
                    }

                    override fun onComplete() {
                        logFile("YCH 查询会员扫码登录结束")
                        useTime = System.currentTimeMillis() - startTime + interval
                        if (loginStatus != 0){
                            loginLoop = false
                            resp?.let {
                                ychClientListener.onLgLogin(it)
                            }
                        }
                    }

                    override fun onNext(t: BaseResult<QrCodeMemberInfoResponse?>) {
                        logFile("YCH 查询会员扫码登录完成：${GsonUtil.getInstance()?.toJson(t)}")
                        resp = t.data
                        loginStatus = when (t.data?.Status) {
                            "Waiting" -> 0
                            "Success" -> 1
                            "Fail" -> 2
                            "Expire" -> 3
                            else -> 3
                        }
                    }
                })

                while (loginStatus == -1){
                    delay(interval)
                }

            }while (loginLoop && loginStatus == 0 && useTime < overTime)
        }
    }

    /**
     * 移除查询会员扫码登录任务
     */
    fun removeQueryLgLogin(){
        loginLoop = false
        loginJob?.cancel()
    }

    /**
     * 会员存币
     * @param leaguerId 会员ID
     * @param num 存币数
     * @param remark 备注
     * @param transId 事务ID
     */
    fun repSaveCoinsData(leaguerId: String, num: Long, remark: String, transId: String){
        devNum?.let {
            businessManager?.repSaveCoinsData(leaguerId, num, it, remark, transId, object : Observer<BaseResult<SaveCoinResult?>>{
                var resp: SaveCoinResult? = null
                override fun onSubscribe(d: Disposable) {
                    logFile("YCH 开始上报会员存币数据")

                }

                override fun onError(e: Throwable) {
                    logFile("YCH 上报会员存币数据异常：${e.message}")
                    onComplete()
                }

                override fun onComplete() {
                    logFile("YCH 上报会员存币数据结束")
                    resp?.let {
                        ychClientListener.saveCoinsFinish(it.balance)
                    }
                }

                override fun onNext(t: BaseResult<SaveCoinResult?>) {
                    logFile("YCH 上报会员存币数据完成：${GsonUtil.getInstance()?.toJson(t)}")
                    resp = t.data
                }
            })
        }
    }

    /**
     * 上报核销数据
     * @param codeData 核销码
     * @param channel 团购平台
     * @param transId 事务id
     */
    fun repWriteOffData(codeData: String, channel: String, amount: Long, transId: String = ""){
        devNum?.let {
            businessManager?.repWriteOffData(codeData, transId, amount, channel, it, false, 2, object : Observer<BaseResult<ChannelWaitOffData?>>{
                var resp: ChannelWaitOffData? = null
                override fun onSubscribe(d: Disposable) {
                    logFile("YCH 开始上报核销数据")
                }

                override fun onError(e: Throwable) {
                    logFile("YCH 上报核销数据异常：${e.message}")
                    onComplete()
                }

                override fun onComplete() {
                    logFile("YCH 上报核销数据结束")
                    resp?.let {
                        ychClientListener.writeOffResult(it)
                    }
                }

                override fun onNext(t: BaseResult<ChannelWaitOffData?>) {
                    logFile("YCH 上报核销数据完成：${GsonUtil.getInstance()?.toJson(t)}")
                    resp = t.data
                }
            })
        }
    }

    interface YchClientListener{
        fun registerFailed(errorCode: Long, errorMsg: String?)

        fun needUpdate(vararg updateAddress: String?)

        fun bindStatus(isSuccess: Boolean, deviceNumber: String?)

        fun onError(type: String?, errorCode: Long, msg: String?)

        fun deviceBinding(devNumber: String)

        fun deviceUnBinding()

        fun deviceReBoot()

        fun extractCoin(isMq: Boolean, coins: String, money: String, orderId: String)

        fun getDeviceSetting(dataJson: String?)

        fun setDeviceSetting(dataJson: String?)

        fun changeCashPackage()

        fun updateOrder(orderId: String?, transactionId: String?, deviceStatus: Int, remark: String?)

        fun deviceStatues(status: Int)

        fun loginComplete()

        fun updateCoinsPackage(coinsPackage: MutableList<YchGoodBean>)

        fun updateConfig(configData: GetPayCoinData)

        fun showPayCode(transId: String, orderId: String, orderNumber: String, codeData: String)

        fun onPlaceOrder(transId: String, orderId: String, orderNumber: String, goodId: String, coins: String, money: String)

        fun placeOrderResult(transId: String, paySuccess: Boolean)

        fun showBuyConsumptionCode(codeData: String)

        fun showDevConsumptionCode(codeData: String)

        fun getLoginCode(codeData: String, transId: String)

        fun onLgLogin(loginMemberInfo: QrCodeMemberInfoResponse)

        fun saveCoinsFinish(balance: Long)

        fun writeOffResult(writeOffResult: ChannelWaitOffData)
    }


}